//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_exported import SotoCore

/// Service object for interacting with AWS CostAndUsageReportService service.
///
/// You can use the Amazon Web Services Cost and Usage Report API to programmatically create, query, and delete  Amazon Web Services Cost and Usage Report definitions. Amazon Web Services Cost and Usage Report track the monthly Amazon Web Services costs and usage  associated with your Amazon Web Services account.  The report contains line items for each unique combination of Amazon Web Services product, usage type, and operation that your Amazon Web Services account uses.   You can configure the Amazon Web Services Cost and Usage Report to show only the data that you want, using the Amazon Web Services Cost and Usage Report API. Service Endpoint The Amazon Web Services Cost and Usage Report API provides the following endpoint:   cur.us-east-1.amazonaws.com
public struct CostAndUsageReportService: AWSService {
    // MARK: Member variables

    /// Client used for communication with AWS
    public let client: AWSClient
    /// Service configuration
    public let config: AWSServiceConfig

    // MARK: Initialization

    /// Initialize the CostAndUsageReportService client
    /// - parameters:
    ///     - client: AWSClient used to process requests
    ///     - region: Region of server you want to communicate with. This will override the partition parameter.
    ///     - partition: AWS partition where service resides, standard (.aws), china (.awscn), government (.awsusgov).
    ///     - endpoint: Custom endpoint URL to use instead of standard AWS servers
    ///     - middleware: Middleware chain used to edit requests before they are sent and responses before they are decoded 
    ///     - timeout: Timeout value for HTTP requests
    ///     - byteBufferAllocator: Allocator for ByteBuffers
    ///     - options: Service options
    public init(
        client: AWSClient,
        region: SotoCore.Region? = nil,
        partition: AWSPartition = .aws,
        endpoint: String? = nil,
        middleware: AWSMiddlewareProtocol? = nil,
        timeout: TimeAmount? = nil,
        byteBufferAllocator: ByteBufferAllocator = ByteBufferAllocator(),
        options: AWSServiceConfig.Options = []
    ) {
        self.client = client
        self.config = AWSServiceConfig(
            region: region,
            partition: region?.partition ?? partition,
            amzTarget: "AWSOrigamiServiceGatewayService",
            serviceName: "CostAndUsageReportService",
            serviceIdentifier: "cur",
            serviceProtocol: .json(version: "1.1"),
            apiVersion: "2017-01-06",
            endpoint: endpoint,
            errorType: CostAndUsageReportServiceErrorType.self,
            middleware: middleware,
            timeout: timeout,
            byteBufferAllocator: byteBufferAllocator,
            options: options
        )
    }





    // MARK: API Calls

    /// Deletes the specified report. Any tags associated with the report are also deleted.
    @Sendable
    @inlinable
    public func deleteReportDefinition(_ input: DeleteReportDefinitionRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> DeleteReportDefinitionResponse {
        try await self.client.execute(
            operation: "DeleteReportDefinition", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Deletes the specified report. Any tags associated with the report are also deleted.
    ///
    /// Parameters:
    ///   - reportName: The name of the report that you want to delete. The name must be unique, is case sensitive, and can't include spaces.
    ///   - logger: Logger use during operation
    @inlinable
    public func deleteReportDefinition(
        reportName: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> DeleteReportDefinitionResponse {
        let input = DeleteReportDefinitionRequest(
            reportName: reportName
        )
        return try await self.deleteReportDefinition(input, logger: logger)
    }

    /// Lists the Amazon Web Services Cost and Usage Report available to this account.
    @Sendable
    @inlinable
    public func describeReportDefinitions(_ input: DescribeReportDefinitionsRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> DescribeReportDefinitionsResponse {
        try await self.client.execute(
            operation: "DescribeReportDefinitions", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Lists the Amazon Web Services Cost and Usage Report available to this account.
    ///
    /// Parameters:
    ///   - maxResults: 
    ///   - nextToken: 
    ///   - logger: Logger use during operation
    @inlinable
    public func describeReportDefinitions(
        maxResults: Int? = nil,
        nextToken: String? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> DescribeReportDefinitionsResponse {
        let input = DescribeReportDefinitionsRequest(
            maxResults: maxResults, 
            nextToken: nextToken
        )
        return try await self.describeReportDefinitions(input, logger: logger)
    }

    /// Lists the tags associated with the specified report definition.
    @Sendable
    @inlinable
    public func listTagsForResource(_ input: ListTagsForResourceRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> ListTagsForResourceResponse {
        try await self.client.execute(
            operation: "ListTagsForResource", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Lists the tags associated with the specified report definition.
    ///
    /// Parameters:
    ///   - reportName: The report name of the report definition that tags are to be returned for.
    ///   - logger: Logger use during operation
    @inlinable
    public func listTagsForResource(
        reportName: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> ListTagsForResourceResponse {
        let input = ListTagsForResourceRequest(
            reportName: reportName
        )
        return try await self.listTagsForResource(input, logger: logger)
    }

    /// Allows you to programmatically update your report preferences.
    @Sendable
    @inlinable
    public func modifyReportDefinition(_ input: ModifyReportDefinitionRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> ModifyReportDefinitionResponse {
        try await self.client.execute(
            operation: "ModifyReportDefinition", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Allows you to programmatically update your report preferences.
    ///
    /// Parameters:
    ///   - reportDefinition: 
    ///   - reportName: 
    ///   - logger: Logger use during operation
    @inlinable
    public func modifyReportDefinition(
        reportDefinition: ReportDefinition,
        reportName: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> ModifyReportDefinitionResponse {
        let input = ModifyReportDefinitionRequest(
            reportDefinition: reportDefinition, 
            reportName: reportName
        )
        return try await self.modifyReportDefinition(input, logger: logger)
    }

    /// Creates a new report using the description that you provide.
    @Sendable
    @inlinable
    public func putReportDefinition(_ input: PutReportDefinitionRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> PutReportDefinitionResponse {
        try await self.client.execute(
            operation: "PutReportDefinition", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Creates a new report using the description that you provide.
    ///
    /// Parameters:
    ///   - reportDefinition: Represents the output of the PutReportDefinition operation. The content consists of the detailed  metadata and data file information.
    ///   - tags: The tags to be assigned to the report definition resource.
    ///   - logger: Logger use during operation
    @inlinable
    public func putReportDefinition(
        reportDefinition: ReportDefinition,
        tags: [Tag]? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> PutReportDefinitionResponse {
        let input = PutReportDefinitionRequest(
            reportDefinition: reportDefinition, 
            tags: tags
        )
        return try await self.putReportDefinition(input, logger: logger)
    }

    /// Associates a set of tags with a report definition.
    @Sendable
    @inlinable
    public func tagResource(_ input: TagResourceRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> TagResourceResponse {
        try await self.client.execute(
            operation: "TagResource", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Associates a set of tags with a report definition.
    ///
    /// Parameters:
    ///   - reportName: The report name of the report definition that tags are to be associated with.
    ///   - tags: The tags to be assigned to the report definition resource.
    ///   - logger: Logger use during operation
    @inlinable
    public func tagResource(
        reportName: String,
        tags: [Tag],
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> TagResourceResponse {
        let input = TagResourceRequest(
            reportName: reportName, 
            tags: tags
        )
        return try await self.tagResource(input, logger: logger)
    }

    /// Disassociates a set of tags from a report definition.
    @Sendable
    @inlinable
    public func untagResource(_ input: UntagResourceRequest, logger: Logger = AWSClient.loggingDisabled) async throws -> UntagResourceResponse {
        try await self.client.execute(
            operation: "UntagResource", 
            path: "/", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Disassociates a set of tags from a report definition.
    ///
    /// Parameters:
    ///   - reportName: The report name of the report definition that tags are to be disassociated from.
    ///   - tagKeys: The tags to be disassociated from the report definition resource.
    ///   - logger: Logger use during operation
    @inlinable
    public func untagResource(
        reportName: String,
        tagKeys: [String],
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> UntagResourceResponse {
        let input = UntagResourceRequest(
            reportName: reportName, 
            tagKeys: tagKeys
        )
        return try await self.untagResource(input, logger: logger)
    }
}

extension CostAndUsageReportService {
    /// Initializer required by `AWSService.with(middlewares:timeout:byteBufferAllocator:options)`. You are not able to use this initializer directly as there are not public
    /// initializers for `AWSServiceConfig.Patch`. Please use `AWSService.with(middlewares:timeout:byteBufferAllocator:options)` instead.
    public init(from: CostAndUsageReportService, patch: AWSServiceConfig.Patch) {
        self.client = from.client
        self.config = from.config.with(patch: patch)
    }
}

// MARK: Paginators

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension CostAndUsageReportService {
    /// Return PaginatorSequence for operation ``describeReportDefinitions(_:logger:)``.
    ///
    /// - Parameters:
    ///   - input: Input for operation
    ///   - logger: Logger used for logging
    @inlinable
    public func describeReportDefinitionsPaginator(
        _ input: DescribeReportDefinitionsRequest,
        logger: Logger = AWSClient.loggingDisabled
    ) -> AWSClient.PaginatorSequence<DescribeReportDefinitionsRequest, DescribeReportDefinitionsResponse> {
        return .init(
            input: input,
            command: self.describeReportDefinitions,
            inputKey: \DescribeReportDefinitionsRequest.nextToken,
            outputKey: \DescribeReportDefinitionsResponse.nextToken,
            logger: logger
        )
    }
    /// Return PaginatorSequence for operation ``describeReportDefinitions(_:logger:)``.
    ///
    /// - Parameters:
    ///   - maxResults: 
    ///   - logger: Logger used for logging
    @inlinable
    public func describeReportDefinitionsPaginator(
        maxResults: Int? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) -> AWSClient.PaginatorSequence<DescribeReportDefinitionsRequest, DescribeReportDefinitionsResponse> {
        let input = DescribeReportDefinitionsRequest(
            maxResults: maxResults
        )
        return self.describeReportDefinitionsPaginator(input, logger: logger)
    }
}

extension CostAndUsageReportService.DescribeReportDefinitionsRequest: AWSPaginateToken {
    @inlinable
    public func usingPaginationToken(_ token: String) -> CostAndUsageReportService.DescribeReportDefinitionsRequest {
        return .init(
            maxResults: self.maxResults,
            nextToken: token
        )
    }
}
